<?php

namespace lico;

/**
 * ioc容器
 */

class Container
{
    //装容器得碗
    protected static $_bowl;

    /**
     * 绑定
     *
     * @param [string] $class
     * @param array $param
     * @param bool $shared
     * @return object
     */
    public static function bind($class,$param = [],$shared = false)
    {
        $ReflectionClass = new \ReflectionClass($class);

        $constructor = $ReflectionClass->getConstructor();//获取构造方法

        $argClassParam = [];
        foreach ($constructor->getParameters() as $arg) {
            $argClass = $arg->getClass();
            if ($argClass) { //参数是类则递归
                //类名
                $argClassName = $argClass->getName();
                //递归返回依赖得类实例
                $argClassParam[] = self::bind($argClassName,[],$shared);
            }
        } 

        $argClassParam = array_merge($argClassParam, $param);
        //返回类得新实例
        $newClass = $ReflectionClass->newInstanceArgs($argClassParam);

        if ($shared) {
            if ( !isset(self::$_bowl[$class]) ) {
                self::$_bowl[$class] = $newClass;
            }
            return self::$_bowl[$class];
        }else{
            return $newClass;
        } 
    }
    
    /**
     * 存储类对象，静态化
     *
     * @param [string] $class
     * @return object
     */
    public static function setBowl($class,$param=[],$shared=false)
    {
        $newClass = self::bind($class,$param,$shared);
        self::$_bowl[$class] = $newClass; 

        return self::$_bowl[$class];
    }

    /**
     * 获取类
     *
     * @param [type] $class
     * @return void
     */
    public static function getBowl($class=null,$param=[],$shared=false){

        if ($class && !isset(self::$_bowl[$class])) {
            self::setBowl($class,$param,$shared);
        }

        return !$class ? self::$_bowl  : self::$_bowl[$class];
    }

}
